import 'package:dio/dio.dart';
import 'package:enjoy_plus_hm/utils/eventBus.dart';
import 'package:enjoy_plus_hm/utils/token.dart';

class NetworkService {
  //1. 初始化 dio,_私有化
  Dio _dio = Dio();
  // 2.配置 dio,在初始化dio的时候进行配置
  NetworkService() {
    // 设置 dio 实例的全局配置
    _dio.options.baseUrl = "https://live-api.itheima.net/";
    // 配置连接超时时间
    _dio.options.connectTimeout = Duration(seconds: 15);
    // 配置接收数据超时时间
    _dio.options.receiveTimeout = Duration(seconds: 15);
    // 设置请求头，指定内容类型为 JSON
    _dio.options.headers = {'Content-Type': 'application/json'};
    // 添加拦截器，用于处理请求或响应
    _addInterceptors();
  }
// 3.添加拦截器
  void _addInterceptors() {
    // 官网代码
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) async {
        // 请求拦截器：添加公共请求参数、token 等
        // 3.1 获取token
        final token = TokenManager().getToken() ?? '';
        // 3.2 添加token到headers中
        if (token.isNotEmpty) {
          options.headers['Authorization'] = 'Bearer $token';
        }
        return handler.next(options);
      },
      onResponse: (response, handler) {
        // 响应拦截器：统一处理成功响应
        return handler.next(response);
      },
      onError: (DioException error, handler) {
        // 响应拦截器：统一处理错误响应
        return handler.next(error);
      },
    ));
  }

  // get请求
  // 定义一个名为[Map<String, dynamic>]的变量
  // 该变量是一个字典，键的类型是String，值的类型是dynamic
  // 这种类型的字典可以存储任意类型的值，键必须是字符串
  Future<dynamic> get(String url, {Map<String, dynamic>? params}) async {
    try {
      final response = await _dio.get(url, queryParameters: params);
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }

  // post请求
  Future<dynamic> post(String url, dynamic data) async {
    try {
      final response = await _dio.post(url, data: data);
      // 自定义方法，处理响应
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }

  // put 请求
  Future<dynamic> put(String url, {dynamic data}) async {
    try {
      final response = await _dio.put(url, data: data);
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }

  // delete 请求
  Future<dynamic> delete(String url, {Map<String, dynamic>? data}) async {
    try {
      final response = await _dio.delete(url, data: data);
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }

  // 成功的情况
  dynamic handleResponse(Response response) {
    // 发送成功，响应码正确
    if (response.statusCode! >= 200 && response.statusCode! < 300) {
      return response.data;
    } else {
      // 响应码错误
      throw Exception('请求失败，状态码：${response.statusCode}');
    }
  }

  // 失败的情况
  dynamic handleError(error) async {
    if (error is DioException) {
      // 网络连接超时
      if (error.type == DioExceptionType.connectionTimeout ||
          error.type == DioExceptionType.receiveTimeout) {
        throw Exception('网络连接超时');
      } else if (error.type == DioExceptionType.badResponse) {
        // 响应错误
        if (error.response?.statusCode == 401) {
          // 服务器错误
          // 删除token
          await TokenManager().removeToken();
          // 跳转到登录页面---通过eventBus触发LogoutEvent事件
          eventBus.fire(LogoutEvent('请重新登录'));
        } else {
          throw Exception('响应错误，状态码：${error.response?.statusCode}');
        }
      } else {
        throw Exception('网络请求错误：$error');
      }
    } else {
      throw Exception('未知错误：$error');
    }
  }
}

// 导出
final MyHttp = NetworkService();
